Conversation
|
Warning Rate limit exceeded
⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthrough데이터베이스 기반 다국어 온보드 목록과 로케일 해석을 추가하고, 멤버 도메인을 enum 기반 필드에서 code(문자열) 기반 필드로 전환했습니다. 정적 상수 클래스들이 제거되고 관련 DTO/서비스/컨트롤러/설정이 현지화 로직으로 대체되었습니다. Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant MemberController
participant LocalizedOnboardQueryService
participant LocalizedOnboardCategoryRepository
participant Database
participant KareerLocaleResolver
Client->>MemberController: GET /onboard/universities (X-Preferred-Language: ko)
MemberController->>KareerLocaleResolver: resolveLocale(request)
KareerLocaleResolver-->>MemberController: Locale("ko")
MemberController->>LocalizedOnboardQueryService: getUniversities()
LocalizedOnboardQueryService->>LocalizedOnboardCategoryRepository: findAllByTypeOrderByUseOrderAscIdAsc(UNIVERSITY)
LocalizedOnboardCategoryRepository->>Database: query with translations (EntityGraph)
Database-->>LocalizedOnboardCategoryRepository: entities + translations
LocalizedOnboardCategoryRepository-->>LocalizedOnboardQueryService: List<LocalizedOnboardCategory>
LocalizedOnboardQueryService->>LocalizedOnboardQueryService: resolveLabelByCode(type, code) per item (locale fallbacks)
LocalizedOnboardQueryService-->>MemberController: OnboardUniversitiesResponse(List<LocalizedItemResponse>)
MemberController-->>Client: 200 OK {universities: [{code,label}, ...]}
sequenceDiagram
participant Client
participant MemberService
participant MemberRepository
participant LocalizedOnboardQueryService
participant MemberInfoResponse
Client->>MemberService: GET /members/{id}
MemberService->>MemberRepository: findById(id)
MemberRepository-->>MemberService: Member (countryCode, primaryMajorCode, ...)
MemberService->>LocalizedOnboardQueryService: resolveLabelByCode(COUNTRY, countryCode)
LocalizedOnboardQueryService-->>MemberService: countryLabel
MemberService->>LocalizedOnboardQueryService: resolveLabelByCode(MAJOR, primaryMajorCode)
LocalizedOnboardQueryService-->>MemberService: majorLabel
MemberService->>MemberInfoResponse: of(member, memberVisa, countryLabel, majorLabel, ...)
MemberInfoResponse-->>MemberService: MemberInfoResponse
MemberService-->>Client: 200 OK {...}
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 8
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
src/main/java/org/sopt/kareer/domain/member/entity/MemberVisa.java (1)
40-52:⚠️ Potential issue | 🔴 Critical
visaPoint제거가 불완전하여 테스트 컴파일이 실패합니다.
MemberVisa엔티티에서visaPoint필드가 완전히 제거되었으나, 테스트 코드가 여전히 이를 참조하고 있습니다:
MemberVisaFixture.java라인 17, 28, 39:.visaPoint(...)빌더 메서드 호출 → 메서드 없음 (컴파일 실패)MemberServiceTest.java라인 101:.getVisaPoint()게터 호출 → 메서드 없음 (컴파일 실패)MemberOnboardRequest.java: 여전히visaPoint필드 존재하고 D10 비자에 대해 필수 검증MemberService.java:createMemberVisa()호출 시visaPoint전달하지 않음 (요청값 버려짐)요청 DTO와 테스트 코드도 동일한 PR에서 함께 정리해야 합니다.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/main/java/org/sopt/kareer/domain/member/entity/MemberVisa.java` around lines 40 - 52, MemberVisa still has visaPoint removed but tests and DTOs reference it; remove all remaining visaPoint usages and align API/signatures: delete the visaPoint field and any D10-specific validation from MemberOnboardRequest, update MemberService.createMemberVisa call sites to match the new signature (no visaPoint argument), and update test fixtures and assertions—remove .visaPoint(...) builder calls in MemberVisaFixture, remove .getVisaPoint() usages in MemberServiceTest and any assertions depending on it; ensure MemberService and MemberOnboardRequest constructors/mapper logic no longer expect or propagate visaPoint and rebuild tests to assert on existing fields (e.g., visaType, visaStatus, visaStartDate, visaExpiredAt).src/main/java/org/sopt/kareer/domain/member/service/MemberService.java (1)
121-150:⚠️ Potential issue | 🟠 Major
preparationStatuses가 null이면 여기서 NPE가 발생합니다.
MemberOnboardV2Request에서preparationStatuses는 검증 어노테이션이 없어 null이 가능한 반면, 라인 145의String.join은 null이 전달되면 즉시NullPointerException을 던집니다. 요청에서 이 필드를 빠뜨리기만 해도 온보딩이 500 에러로 실패합니다. 빈 리스트 기본값 처리 또는@NotNull검증을 추가해 주세요.🛠️ null-safe 처리 예시
String fieldOfInterest = String.join(",", request.fieldsOfInterests()); - String preparationStatus = String.join(",", request.preparationStatuses()); + String preparationStatus = request.preparationStatuses() == null + ? "" + : String.join(",", request.preparationStatuses());🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/main/java/org/sopt/kareer/domain/member/service/MemberService.java` around lines 121 - 150, onboardMemberV2 currently calls String.join on request.preparationStatuses() (and similarly fieldsOfInterests), which throws NPE if those lists are null; update MemberService.onboardMemberV2 to defensively handle nulls by defaulting to empty lists before joining (e.g., replace String.join(",", request.preparationStatuses()) with a null-safe expression that uses an empty list or empty string when request.preparationStatuses() is null) or alternatively add `@NotNull` to MemberOnboardV2Request.preparationStatuses() (and fieldsOfInterests if desired) so the DTO is validated; ensure to update both preparationStatuses and fieldsOfInterests usages and keep the rest of member.updateInfoV2 call unchanged.
🧹 Nitpick comments (5)
src/main/java/org/sopt/kareer/domain/member/dto/response/MypageResponse.java (1)
54-59: 동일 타입 파라미터가 너무 많아 호출 순서 실수에 취약합니다.
String라벨 인자가 5개 연속이라 호출부에서 순서를 바꿔도 컴파일로 못 잡습니다. 라벨 묶음을 별도 record/VO로 감싸거나 builder에서 직접 채우는 쪽이 더 안전합니다.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/main/java/org/sopt/kareer/domain/member/dto/response/MypageResponse.java` around lines 54 - 59, The static factory MypageResponse.of currently takes five consecutive String label parameters (countryLabel, primaryMajorLabel, universityLabel, degreeLabel, englishLevelLabel) which is error-prone; refactor by introducing a compact value object/record (e.g., MypageLabels or LabelsRecord) to hold those label fields and change MypageResponse.of to accept that single Labels type (or add a builder on MypageResponse that accepts/sets labels via a Labels object); update all call sites that invoke MypageResponse.of to construct and pass the new Labels instance (or use the builder) and adjust MemberVisa/Member usages accordingly so parameter order mistakes are prevented.src/main/java/org/sopt/kareer/domain/member/dto/response/MemberInfoResponse.java (2)
5-6: 와일드카드 import 사용와일드카드 import (
.*)는 어떤 클래스가 실제로 사용되는지 파악하기 어렵게 만들고, 이름 충돌 가능성을 높입니다. 명시적 import를 사용하면 가독성과 유지보수성이 향상됩니다.♻️ 명시적 import 제안
-import org.sopt.kareer.domain.member.entity.*; -import org.sopt.kareer.domain.member.entity.enums.*; +import org.sopt.kareer.domain.member.entity.Member; +import org.sopt.kareer.domain.member.entity.MemberVisa; +import org.sopt.kareer.domain.member.entity.enums.LanguageLevel; +import org.sopt.kareer.domain.member.entity.enums.VisaType;🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/main/java/org/sopt/kareer/domain/member/dto/response/MemberInfoResponse.java` around lines 5 - 6, Replace the wildcard imports in MemberInfoResponse by listing the exact classes used from org.sopt.kareer.domain.member.entity and org.sopt.kareer.domain.member.entity.enums; update the import statements referenced in MemberInfoResponse (the class name MemberInfoResponse) to explicitly import only the entity classes and enum types referenced in its fields/methods (e.g., specific entity classes and enum names) instead of using org.sopt.kareer.domain.member.entity.* and org.sopt.kareer.domain.member.entity.enums.* to improve clarity and avoid name collisions.
61-86: 파라미터가 많은 팩토리 메서드
of()메서드가 7개의 파라미터를 받고 있으며, 그 중 5개가String타입의 레이블입니다. 동일한 타입의 파라미터가 연속되면 호출 시 순서를 잘못 전달할 위험이 있습니다.향후 파라미터가 더 늘어날 경우, Builder 패턴이나 전용 파라미터 객체(예:
MemberLabelsrecord)를 고려해 보세요.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/main/java/org/sopt/kareer/domain/member/dto/response/MemberInfoResponse.java` around lines 61 - 86, The MemberInfoResponse.of factory method takes many parameters (several consecutive Strings) which risks ordering bugs; refactor by introducing a parameter object or builder: create a MemberLabels record or a MemberInfoResponse.Builder and change MemberInfoResponse.of(Member, MemberVisa, String... ) to accept the new MemberLabels (or use builder setters) and update callers to pass the labels via that object or builder; adjust MemberInfoResponse constructor/fields as needed and keep MemberInfoResponse.of(Member, MemberVisa, MemberLabels) (or remove the static of in favor of Builder.build()) to make parameter grouping explicit and prevent ordering mistakes.src/main/java/org/sopt/kareer/domain/member/service/LocalizedOnboardQueryService.java (1)
61-71: 중복된 Locale 추출 로직Lines 48-50의
resolveLabelByCode와 Lines 62-64의toItemResponses에서 동일한 Locale 추출 로직이 반복됩니다. 헬퍼 메서드로 추출하여 중복을 제거하면 유지보수성이 향상됩니다.♻️ Locale 추출 헬퍼 메서드 제안
+ private record LocaleInfo(String languageTag, String language) {} + + private LocaleInfo extractLocaleInfo() { + Locale locale = LocaleContextHolder.getLocale(); + return new LocaleInfo(locale.toLanguageTag(), locale.getLanguage()); + } + private List<LocalizedItemResponse> toItemResponses(List<LocalizedOnboardCategory> categories) { - Locale locale = LocaleContextHolder.getLocale(); - String languageTag = locale != null ? locale.toLanguageTag() : null; - String language = locale != null ? locale.getLanguage() : null; + LocaleInfo localeInfo = extractLocaleInfo(); return categories.stream() .map(category -> new LocalizedItemResponse( category.getCode(), - resolveLabel(category, languageTag, language))) + resolveLabel(category, localeInfo.languageTag(), localeInfo.language()))) .toList(); }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/main/java/org/sopt/kareer/domain/member/service/LocalizedOnboardQueryService.java` around lines 61 - 71, Extract the duplicated Locale extraction into a private helper used by both resolveLabelByCode and toItemResponses: create a method (e.g., getLocaleLanguageInfo or resolveLocaleInfo) that calls LocaleContextHolder.getLocale(), computes languageTag and language (handling null), and returns them in a small holder (e.g., a simple record/DTO or String[]); then replace the inline Locale/ languageTag/ language logic inside resolveLabelByCode and toItemResponses with a call to this new helper and use its returned values when calling resolveLabel.src/main/java/org/sopt/kareer/domain/member/entity/Member.java (1)
117-149:updateInfoV2()의 입력 검증 부재새로운
updateInfoV2()메서드가 문자열 코드를 직접 받아 저장합니다. 유효하지 않은 코드가 전달될 경우 데이터 무결성 문제가 발생할 수 있습니다.서비스 레이어에서 코드 유효성을 검증하거나, 도메인 로직에서 검증을 추가하는 것이 좋습니다.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/main/java/org/sopt/kareer/domain/member/entity/Member.java` around lines 117 - 149, The updateInfoV2 method on Member accepts raw string codes (countryCode, universityCode, englishLevelCode, degreeCode, primaryMajorCode, etc.) without validation, risking data integrity; add domain-level validation inside Member.updateInfoV2 (or helper methods it calls) to validate/convert those code strings to the appropriate enums/typed values (e.g., Country, University, EnglishLevel, Degree, Major) or lookup services and throw a clear domain exception (e.g., InvalidMemberDataException) on invalid codes, and only set the fields (fieldsOfInterest, preparationStatus, languageLevel, etc.) after successful validation; ensure assertPendingStatus() remains and keep setting status to MemberStatus.ACTIVE only when all validations pass.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In
`@src/main/java/org/sopt/kareer/domain/member/dto/request/MemberOnboardV2Request.java`:
- Around line 16-20: The fields universityCode and countryCode in
MemberOnboardV2Request are annotated with `@NotNull` which allows empty or
whitespace strings; change their validation annotation to `@NotBlank` so
empty/blank values are rejected and label lookup keys remain valid. Update the
annotations on the universityCode and countryCode fields in the
MemberOnboardV2Request class (same style as primaryMajorCode, name, targetJob)
to use `@NotBlank` with an appropriate message.
In `@src/main/java/org/sopt/kareer/domain/member/dto/request/MypageRequest.java`:
- Around line 22-35: MypageRequest has inconsistent validation and misleading
schema examples: change countryCode's annotation from `@NotNull` to `@NotBlank` (and
keep or harmonize validation messages) so empty/blank strings are rejected like
universityCode and primaryMajorCode, and update all `@Schema` example values for
countryCode, universityCode, and primaryMajorCode to show actual code formats
(e.g., "KR" or "AF" for countryCode, a university code token for universityCode,
and a major code token for primaryMajorCode) so API consumers see the expected
code strings; locate and modify the fields countryCode, universityCode, and
primaryMajorCode in class MypageRequest to apply these changes.
In `@src/main/java/org/sopt/kareer/domain/member/entity/enums/EnglishLevel.java`:
- Around line 9-11: The enum EnglishLevel was changed to use lowercase
descriptions which will break compatibility with existing DB values like
"Beginner"/"Intermediate"/"Advanced"; revert the enum descriptions in
EnglishLevel (the description strings passed to BEGINNER/INTERMEDIATE/ADVANCED)
to the original casing, and/or add a mapping method on EnglishLevel (e.g.,
fromDescription(String) or normalizeDescriptionForDb()) that accepts both
capitalized and lowercase forms and returns the correct enum so Member
persistence (which calls getDescription()) remains compatible; update usages
that serialize/deserialize englishLevelCode to use this mapping.
In
`@src/main/java/org/sopt/kareer/domain/member/entity/LocalizedOnboardCategory.java`:
- Around line 25-42: Add a unique constraint for the combination of fields type
and code on the LocalizedOnboardCategory entity and in the DB migration: update
the `@Table` annotation on class LocalizedOnboardCategory to declare a unique
constraint over columns "type" and "code" (e.g., uniqueConstraints =
`@UniqueConstraint`(columnNames = {"type","code"}, name =
"uk_localized_onboard_type_code")), and create a corresponding migration that
adds the unique index/constraint on the localized_onboard_category table
(resolving or deduplicating any existing duplicate rows beforehand so the
migration can apply cleanly); this will ensure findByTypeAndCode() returns a
single deterministic row.
In
`@src/main/java/org/sopt/kareer/domain/member/entity/LocalizedOnboardCategoryTranslation.java`:
- Around line 17-34: Add a DB-level unique constraint on (category_id, language)
to prevent duplicates: update the JPA entity LocalizedOnboardCategoryTranslation
by adding a uniqueConstraints entry on `@Table` for the (category_id, language)
pair, and create a database migration that (a) resolves or deduplicates any
existing duplicate rows for localized_onboard_category_translation and (b) adds
a UNIQUE constraint or unique index on category_id and language. Also review
callers like LocalizedOnboardCategory.updateTranslation(), addTranslation() and
any repository usages that assume multiple rows per language to ensure they
handle the uniqueness guarantee after migration.
In `@src/main/java/org/sopt/kareer/domain/member/entity/Member.java`:
- Around line 192-212: The updateProfile method mixes enum parameters (Degree,
EnglishLevel) with string codes for other fields which is inconsistent; change
the updateProfile signature to accept degreeCode and englishLevelCode as String
(instead of Degree and EnglishLevel), assign them directly to this.degreeCode
and this.englishLevelCode, and update all callers to pass the corresponding code
strings; keep the other parameters (countryCode, universityCode,
primaryMajorCode) unchanged so the API uniformly uses string codes.
In
`@src/main/java/org/sopt/kareer/global/external/ai/builder/context/MemberContextBuilder.java`:
- Around line 31-33: In MemberContextBuilder the university field is incorrectly
populated using member.getCountryCode(), causing "country" and "university" to
share the same value; update the appendLine call that sets "university" to use
member.getUniversityCode() instead (locate the appendLine(sb, "university", ...)
call and replace the getter), leaving the "country" and "primaryMajor" lines
unchanged.
In `@src/test/java/org/sopt/kareer/domain/member/entity/MemberTest.java`:
- Line 41: The test asserts the wrong getter: replace the call to
member.getUniversityCode() with the English level getter
member.getEnglishLevelCode() so the assertion compares the stored EnglishLevel
(e.g., EnglishLevel.BEGINNER) code value; update the assertion in MemberTest
(currently using getUniversityCode) to use getEnglishLevelCode() to validate
English level correctly.
---
Outside diff comments:
In `@src/main/java/org/sopt/kareer/domain/member/entity/MemberVisa.java`:
- Around line 40-52: MemberVisa still has visaPoint removed but tests and DTOs
reference it; remove all remaining visaPoint usages and align API/signatures:
delete the visaPoint field and any D10-specific validation from
MemberOnboardRequest, update MemberService.createMemberVisa call sites to match
the new signature (no visaPoint argument), and update test fixtures and
assertions—remove .visaPoint(...) builder calls in MemberVisaFixture, remove
.getVisaPoint() usages in MemberServiceTest and any assertions depending on it;
ensure MemberService and MemberOnboardRequest constructors/mapper logic no
longer expect or propagate visaPoint and rebuild tests to assert on existing
fields (e.g., visaType, visaStatus, visaStartDate, visaExpiredAt).
In `@src/main/java/org/sopt/kareer/domain/member/service/MemberService.java`:
- Around line 121-150: onboardMemberV2 currently calls String.join on
request.preparationStatuses() (and similarly fieldsOfInterests), which throws
NPE if those lists are null; update MemberService.onboardMemberV2 to defensively
handle nulls by defaulting to empty lists before joining (e.g., replace
String.join(",", request.preparationStatuses()) with a null-safe expression that
uses an empty list or empty string when request.preparationStatuses() is null)
or alternatively add `@NotNull` to MemberOnboardV2Request.preparationStatuses()
(and fieldsOfInterests if desired) so the DTO is validated; ensure to update
both preparationStatuses and fieldsOfInterests usages and keep the rest of
member.updateInfoV2 call unchanged.
---
Nitpick comments:
In
`@src/main/java/org/sopt/kareer/domain/member/dto/response/MemberInfoResponse.java`:
- Around line 5-6: Replace the wildcard imports in MemberInfoResponse by listing
the exact classes used from org.sopt.kareer.domain.member.entity and
org.sopt.kareer.domain.member.entity.enums; update the import statements
referenced in MemberInfoResponse (the class name MemberInfoResponse) to
explicitly import only the entity classes and enum types referenced in its
fields/methods (e.g., specific entity classes and enum names) instead of using
org.sopt.kareer.domain.member.entity.* and
org.sopt.kareer.domain.member.entity.enums.* to improve clarity and avoid name
collisions.
- Around line 61-86: The MemberInfoResponse.of factory method takes many
parameters (several consecutive Strings) which risks ordering bugs; refactor by
introducing a parameter object or builder: create a MemberLabels record or a
MemberInfoResponse.Builder and change MemberInfoResponse.of(Member, MemberVisa,
String... ) to accept the new MemberLabels (or use builder setters) and update
callers to pass the labels via that object or builder; adjust MemberInfoResponse
constructor/fields as needed and keep MemberInfoResponse.of(Member, MemberVisa,
MemberLabels) (or remove the static of in favor of Builder.build()) to make
parameter grouping explicit and prevent ordering mistakes.
In
`@src/main/java/org/sopt/kareer/domain/member/dto/response/MypageResponse.java`:
- Around line 54-59: The static factory MypageResponse.of currently takes five
consecutive String label parameters (countryLabel, primaryMajorLabel,
universityLabel, degreeLabel, englishLevelLabel) which is error-prone; refactor
by introducing a compact value object/record (e.g., MypageLabels or
LabelsRecord) to hold those label fields and change MypageResponse.of to accept
that single Labels type (or add a builder on MypageResponse that accepts/sets
labels via a Labels object); update all call sites that invoke MypageResponse.of
to construct and pass the new Labels instance (or use the builder) and adjust
MemberVisa/Member usages accordingly so parameter order mistakes are prevented.
In `@src/main/java/org/sopt/kareer/domain/member/entity/Member.java`:
- Around line 117-149: The updateInfoV2 method on Member accepts raw string
codes (countryCode, universityCode, englishLevelCode, degreeCode,
primaryMajorCode, etc.) without validation, risking data integrity; add
domain-level validation inside Member.updateInfoV2 (or helper methods it calls)
to validate/convert those code strings to the appropriate enums/typed values
(e.g., Country, University, EnglishLevel, Degree, Major) or lookup services and
throw a clear domain exception (e.g., InvalidMemberDataException) on invalid
codes, and only set the fields (fieldsOfInterest, preparationStatus,
languageLevel, etc.) after successful validation; ensure assertPendingStatus()
remains and keep setting status to MemberStatus.ACTIVE only when all validations
pass.
In
`@src/main/java/org/sopt/kareer/domain/member/service/LocalizedOnboardQueryService.java`:
- Around line 61-71: Extract the duplicated Locale extraction into a private
helper used by both resolveLabelByCode and toItemResponses: create a method
(e.g., getLocaleLanguageInfo or resolveLocaleInfo) that calls
LocaleContextHolder.getLocale(), computes languageTag and language (handling
null), and returns them in a small holder (e.g., a simple record/DTO or
String[]); then replace the inline Locale/ languageTag/ language logic inside
resolveLabelByCode and toItemResponses with a call to this new helper and use
its returned values when calling resolveLabel.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 103e04a2-f4c5-4d4e-81d2-0697449f5c1c
📒 Files selected for processing (30)
src/main/java/org/sopt/kareer/domain/member/controller/MemberController.javasrc/main/java/org/sopt/kareer/domain/member/dto/request/MemberOnboardV2Request.javasrc/main/java/org/sopt/kareer/domain/member/dto/request/MypageRequest.javasrc/main/java/org/sopt/kareer/domain/member/dto/response/LocalizedItemResponse.javasrc/main/java/org/sopt/kareer/domain/member/dto/response/MemberInfoResponse.javasrc/main/java/org/sopt/kareer/domain/member/dto/response/MypageResponse.javasrc/main/java/org/sopt/kareer/domain/member/dto/response/OnboardCountriesResponse.javasrc/main/java/org/sopt/kareer/domain/member/dto/response/OnboardFieldsResponse.javasrc/main/java/org/sopt/kareer/domain/member/dto/response/OnboardMajorsResponse.javasrc/main/java/org/sopt/kareer/domain/member/dto/response/OnboardUniversitiesResponse.javasrc/main/java/org/sopt/kareer/domain/member/entity/LocalizedOnboardCategory.javasrc/main/java/org/sopt/kareer/domain/member/entity/LocalizedOnboardCategoryTranslation.javasrc/main/java/org/sopt/kareer/domain/member/entity/Member.javasrc/main/java/org/sopt/kareer/domain/member/entity/MemberVisa.javasrc/main/java/org/sopt/kareer/domain/member/entity/constants/Field.javasrc/main/java/org/sopt/kareer/domain/member/entity/constants/Major.javasrc/main/java/org/sopt/kareer/domain/member/entity/constants/University.javasrc/main/java/org/sopt/kareer/domain/member/entity/enums/Degree.javasrc/main/java/org/sopt/kareer/domain/member/entity/enums/EnglishLevel.javasrc/main/java/org/sopt/kareer/domain/member/entity/enums/LocalizedOnboardCategoryType.javasrc/main/java/org/sopt/kareer/domain/member/repository/LocalizedOnboardCategoryRepository.javasrc/main/java/org/sopt/kareer/domain/member/service/LocalizedOnboardQueryService.javasrc/main/java/org/sopt/kareer/domain/member/service/MemberService.javasrc/main/java/org/sopt/kareer/domain/member/service/dto/request/MypageCommand.javasrc/main/java/org/sopt/kareer/global/config/InternationalizationConfig.javasrc/main/java/org/sopt/kareer/global/config/locale/KareerLocaleResolver.javasrc/main/java/org/sopt/kareer/global/config/swagger/SwaggerConfig.javasrc/main/java/org/sopt/kareer/global/external/ai/builder/context/MemberContextBuilder.javasrc/main/java/org/sopt/kareer/global/external/ai/builder/query/PolicyQueryBuilder.javasrc/test/java/org/sopt/kareer/domain/member/entity/MemberTest.java
💤 Files with no reviewable changes (3)
- src/main/java/org/sopt/kareer/domain/member/entity/constants/Field.java
- src/main/java/org/sopt/kareer/domain/member/entity/constants/University.java
- src/main/java/org/sopt/kareer/domain/member/entity/constants/Major.java
| @NotNull(message = "대학교 코드는 필수 입력값입니다.") | ||
| String universityCode, | ||
|
|
||
| @NotNull(message = "국가는 필수 입력값입니다.") | ||
| Country country, | ||
| @NotNull(message = "국가 코드는 필수 입력값입니다.") | ||
| String countryCode, |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
cat -n src/main/java/org/sopt/kareer/domain/member/dto/request/MemberOnboardV2Request.javaRepository: team-kareer/kareer-server
Length of output: 2327
🏁 Script executed:
rg -A 3 "universityCode|countryCode" src/main/java/org/sopt/kareer --type java | head -50Repository: team-kareer/kareer-server
Length of output: 4773
🏁 Script executed:
rg "@NotBlank|@NotNull" src/main/java/org/sopt/kareer/domain/member --type java -B 1 | head -40Repository: team-kareer/kareer-server
Length of output: 3237
코드 문자열은 @NotBlank로 검증해야 합니다.
universityCode와 countryCode가 String인데 @NotNull만 사용하고 있어서 "" 또는 공백 문자열이 통과합니다. 같은 레코드의 다른 코드 필드들(primaryMajorCode, name, targetJob)은 모두 @NotBlank를 사용하고 있습니다. 이 두 필드는 이후 라벨 조회 키로 사용되므로 빈 값이 저장되면 매핑이 깨집니다.
수정 예시
- `@NotNull`(message = "대학교 코드는 필수 입력값입니다.")
+ `@NotBlank`(message = "대학교 코드는 필수 입력값입니다.")
String universityCode,
- `@NotNull`(message = "국가 코드는 필수 입력값입니다.")
+ `@NotBlank`(message = "국가 코드는 필수 입력값입니다.")
String countryCode,📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| @NotNull(message = "대학교 코드는 필수 입력값입니다.") | |
| String universityCode, | |
| @NotNull(message = "국가는 필수 입력값입니다.") | |
| Country country, | |
| @NotNull(message = "국가 코드는 필수 입력값입니다.") | |
| String countryCode, | |
| `@NotBlank`(message = "대학교 코드는 필수 입력값입니다.") | |
| String universityCode, | |
| `@NotBlank`(message = "국가 코드는 필수 입력값입니다.") | |
| String countryCode, |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In
`@src/main/java/org/sopt/kareer/domain/member/dto/request/MemberOnboardV2Request.java`
around lines 16 - 20, The fields universityCode and countryCode in
MemberOnboardV2Request are annotated with `@NotNull` which allows empty or
whitespace strings; change their validation annotation to `@NotBlank` so
empty/blank values are rejected and label lookup keys remain valid. Update the
annotations on the universityCode and countryCode fields in the
MemberOnboardV2Request class (same style as primaryMajorCode, name, targetJob)
to use `@NotBlank` with an appropriate message.
| @NotNull(message = "국가코드는 필수 입력값입니다.") | ||
| String countryCode, | ||
|
|
||
| @Schema(description = "학위", example = "DOMESTIC_ASSOCIATE") | ||
| @NotNull(message = "학위는 필수 입력값입니다.") | ||
| Degree degree, | ||
|
|
||
| @Schema(description = "대학", example = "Konkuk University") | ||
| @NotBlank(message = "대학은 필수 입력값입니다.") | ||
| String university, | ||
| @NotBlank(message = "대학코드는 필수 입력값입니다.") | ||
| String universityCode, | ||
|
|
||
| @Schema(description = "전공", example = "Computer Science") | ||
| @NotBlank(message = "전공은 필수 입력값입니다.") | ||
| String primaryMajor, | ||
| @NotBlank(message = "전공코드는 필수 입력값입니다.") | ||
| String primaryMajorCode, |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
find . -type f -name "MypageRequest.java" | head -5Repository: team-kareer/kareer-server
Length of output: 145
🏁 Script executed:
cat -n src/main/java/org/sopt/kareer/domain/member/dto/request/MypageRequest.java | head -50Repository: team-kareer/kareer-server
Length of output: 2152
코드형 요청 계약을 일관되게 맞춰 주세요.
countryCode만 @NotNull이라 ""/공백 문자열이 통과하는 반면, universityCode와 primaryMajorCode는 @NotBlank로 보호됩니다. 또한 세 필드의 @Schema example이 모두 표시명("Afghanistan", "Konkuk University", "Computer Science")이라 실제 코드 형식을 명시하지 않아 API 소비자 혼동을 야기합니다.
🧩 수정 예시
- `@Schema`(description = "국가", example = "Afghanistan")
- `@NotNull`(message = "국가코드는 필수 입력값입니다.")
+ `@Schema`(description = "국가 코드", example = "afghanistan")
+ `@NotBlank`(message = "국가코드는 필수 입력값입니다.")
String countryCode,
@@
- `@Schema`(description = "대학", example = "Konkuk University")
+ `@Schema`(description = "대학 코드", example = "konkuk-university")
`@NotBlank`(message = "대학코드는 필수 입력값입니다.")
String universityCode,
@@
- `@Schema`(description = "전공", example = "Computer Science")
+ `@Schema`(description = "전공 코드", example = "computer-science")
`@NotBlank`(message = "전공코드는 필수 입력값입니다.")
String primaryMajorCode,🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/main/java/org/sopt/kareer/domain/member/dto/request/MypageRequest.java`
around lines 22 - 35, MypageRequest has inconsistent validation and misleading
schema examples: change countryCode's annotation from `@NotNull` to `@NotBlank` (and
keep or harmonize validation messages) so empty/blank strings are rejected like
universityCode and primaryMajorCode, and update all `@Schema` example values for
countryCode, universityCode, and primaryMajorCode to show actual code formats
(e.g., "KR" or "AF" for countryCode, a university code token for universityCode,
and a major code token for primaryMajorCode) so API consumers see the expected
code strings; locate and modify the fields countryCode, universityCode, and
primaryMajorCode in class MypageRequest to apply these changes.
| BEGINNER("beginner"), | ||
| INTERMEDIATE("intermediate"), | ||
| ADVANCED("advanced") |
There was a problem hiding this comment.
기존 englishLevelCode 데이터 호환성 깨짐 위험이 있습니다.
description 포맷을 소문자로 바꾸면, 기존에 저장된 "Beginner", "Intermediate", "Advanced" 값과 불일치가 발생할 수 있습니다. Member 저장 로직이 getDescription()을 그대로 쓰고 있으므로, 배포 시점에 DB 정규화 마이그레이션(기존 값 소문자 변환) 또는 조회 시 하위호환 매핑이 필요합니다.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/main/java/org/sopt/kareer/domain/member/entity/enums/EnglishLevel.java`
around lines 9 - 11, The enum EnglishLevel was changed to use lowercase
descriptions which will break compatibility with existing DB values like
"Beginner"/"Intermediate"/"Advanced"; revert the enum descriptions in
EnglishLevel (the description strings passed to BEGINNER/INTERMEDIATE/ADVANCED)
to the original casing, and/or add a mapping method on EnglishLevel (e.g.,
fromDescription(String) or normalizeDescriptionForDb()) that accepts both
capitalized and lowercase forms and returns the correct enum so Member
persistence (which calls getDescription()) remains compatible; update usages
that serialize/deserialize englishLevelCode to use this mapping.
| @Table(name = "localized_onboard_category") | ||
| @Getter | ||
| @NoArgsConstructor(access = AccessLevel.PROTECTED) | ||
| public class LocalizedOnboardCategory { | ||
|
|
||
| @Id | ||
| @GeneratedValue(strategy = GenerationType.IDENTITY) | ||
| private Long id; | ||
|
|
||
| @Enumerated(EnumType.STRING) | ||
| @Column(nullable = false) | ||
| private LocalizedOnboardCategoryType type; | ||
|
|
||
| @Column(nullable = false) | ||
| private String code; | ||
|
|
||
| @Column(name = "use_order", nullable = false) | ||
| private int useOrder; |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# Find all references to LocalizedOnboardCategory
rg "LocalizedOnboardCategory" --type java -A 3 -B 1Repository: team-kareer/kareer-server
Length of output: 20055
🏁 Script executed:
# Look for migration files related to this table
fd ".*onboard.*" --type f | grep -i migrationRepository: team-kareer/kareer-server
Length of output: 51
🏁 Script executed:
# Check the repository or query methods for this entity
rg "localizedOnboardCategory|LocalizedOnboardCategory" --type java | head -30Repository: team-kareer/kareer-server
Length of output: 5452
🏁 Script executed:
# Search for any unique constraint definitions in existing migrations
rg "uniqueConstraint|UNIQUE|uk_" --type sql --type java | head -20Repository: team-kareer/kareer-server
Length of output: 808
🏁 Script executed:
# Look for Flyway or Liquibase migration files
find . -type f \( -name "*.sql" -o -name "*.xml" \) | grep -i "migration\|flyway\|liquibase" | head -20Repository: team-kareer/kareer-server
Length of output: 51
🏁 Script executed:
# Search for migration files that might contain onboard_category table definition
rg "localized_onboard_category|onboard_category" --type sqlRepository: team-kareer/kareer-server
Length of output: 217
🏁 Script executed:
# Read complete LocalizedOnboardCategory entity definition
cat -n src/main/java/org/sopt/kareer/domain/member/entity/LocalizedOnboardCategory.javaRepository: team-kareer/kareer-server
Length of output: 3033
🏁 Script executed:
# Search for migration files more broadly
find . -type f -name "*.sql" | head -30Repository: team-kareer/kareer-server
Length of output: 51
🏁 Script executed:
# Also check for migration directories
find . -type d -name "*migration*" -o -type d -name "*flyway*" -o -type d -name "*liquibase*"Repository: team-kareer/kareer-server
Length of output: 51
🏁 Script executed:
# Check the resolveLabelByCode method to see how it handles the Optional
rg "resolveLabelByCode" -A 15 --type javaRepository: team-kareer/kareer-server
Length of output: 8086
type과 code 조합에 유니크 제약을 추가하세요.
findByTypeAndCode() 메서드로 단건 조회를 하는데, 현재 제약이 없으면 같은 조합의 행이 여러 개 존재할 때 임의의 행이 반환되어 잘못된 라벨이 매핑될 수 있습니다. 엔티티의 @Table 어노테이션과 데이터베이스 마이그레이션에 유니크 제약을 추가하세요.
🛠️ 제약 추가 예시
+import jakarta.persistence.UniqueConstraint;
...
-@Table(name = "localized_onboard_category")
+@Table(
+ name = "localized_onboard_category",
+ uniqueConstraints = `@UniqueConstraint`(
+ name = "uk_localized_onboard_category_type_code",
+ columnNames = {"type", "code"}
+ )
+)
public class LocalizedOnboardCategory {🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In
`@src/main/java/org/sopt/kareer/domain/member/entity/LocalizedOnboardCategory.java`
around lines 25 - 42, Add a unique constraint for the combination of fields type
and code on the LocalizedOnboardCategory entity and in the DB migration: update
the `@Table` annotation on class LocalizedOnboardCategory to declare a unique
constraint over columns "type" and "code" (e.g., uniqueConstraints =
`@UniqueConstraint`(columnNames = {"type","code"}, name =
"uk_localized_onboard_type_code")), and create a corresponding migration that
adds the unique index/constraint on the localized_onboard_category table
(resolving or deduplicating any existing duplicate rows beforehand so the
migration can apply cleanly); this will ensure findByTypeAndCode() returns a
single deterministic row.
| @Table(name = "localized_onboard_category_translation") | ||
| @Getter | ||
| @NoArgsConstructor(access = AccessLevel.PROTECTED) | ||
| public class LocalizedOnboardCategoryTranslation { | ||
|
|
||
| @Id | ||
| @GeneratedValue(strategy = GenerationType.IDENTITY) | ||
| private Long id; | ||
|
|
||
| @ManyToOne(fetch = FetchType.LAZY) | ||
| @JoinColumn(name = "category_id", nullable = false) | ||
| private LocalizedOnboardCategory category; | ||
|
|
||
| @Column(nullable = false) | ||
| private String language; | ||
|
|
||
| @Column(nullable = false) | ||
| private String label; |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# Find and examine the LocalizedOnboardCategoryTranslation entity
find . -type f -name "LocalizedOnboardCategoryTranslation.java" | head -5Repository: team-kareer/kareer-server
Length of output: 162
🏁 Script executed:
# Find the parent entity LocalizedOnboardCategory
find . -type f -name "LocalizedOnboardCategory.java" | head -5Repository: team-kareer/kareer-server
Length of output: 151
🏁 Script executed:
# Search for updateTranslation and addTranslation methods
rg -A 10 "updateTranslation|addTranslation" --type javaRepository: team-kareer/kareer-server
Length of output: 1687
🏁 Script executed:
# Check for any migration files or constraints definitions
find . -type f \( -name "*.sql" -o -name "*migration*" -o -name "*Migration*.java" \) | grep -i "localized\|onboard" | head -10Repository: team-kareer/kareer-server
Length of output: 51
🏁 Script executed:
# Search for UniqueConstraint usage in the codebase
rg "UniqueConstraint" --type java -B 2 -A 2Repository: team-kareer/kareer-server
Length of output: 1726
🏁 Script executed:
# Read the full LocalizedOnboardCategoryTranslation entity
cat src/main/java/org/sopt/kareer/domain/member/entity/LocalizedOnboardCategoryTranslation.javaRepository: team-kareer/kareer-server
Length of output: 1498
🏁 Script executed:
# Read the full LocalizedOnboardCategory entity to see the complete context
cat src/main/java/org/sopt/kareer/domain/member/entity/LocalizedOnboardCategory.javaRepository: team-kareer/kareer-server
Length of output: 2522
🏁 Script executed:
# Check if there are any constraints defined elsewhere for this translation table
rg "localized_onboard_category_translation" --type sql,javaRepository: team-kareer/kareer-server
Length of output: 101
🏁 Script executed:
# Search for migration files or database schema definitions
find . -type f \( -name "*.sql" -o -name "*Migration.java" -o -name "*V*.sql" \) | xargs rg "localized_onboard_category_translation" 2>/dev/null || echo "No migration files found with this table"Repository: team-kareer/kareer-server
Length of output: 216
🏁 Script executed:
# Search across the codebase for any unique constraint definitions or migrations
rg "localized_onboard_category_translation" -t javaRepository: team-kareer/kareer-server
Length of output: 216
(category_id, language) 고유성을 데이터베이스 레벨에서 강제해야 합니다.
상위 엔티티의 updateTranslation()은 언어당 번역 1개를 전제로 findFirst()로 동작하는데, 현재 (category_id, language) 중복이 DB에서 허용됩니다. addTranslation()이 중복 체크 없이 단순 추가만 수행하므로, 의도치 않은 중복 호출 시 어떤 라벨이 조회될지 비결정적입니다. 엔티티 선언과 마이그레이션 모두에서 유니크 제약으로 고정하는 것이 안전합니다.
제약 추가 예시
+import jakarta.persistence.UniqueConstraint;
...
-@Table(name = "localized_onboard_category_translation")
+@Table(
+ name = "localized_onboard_category_translation",
+ uniqueConstraints = `@UniqueConstraint`(
+ name = "uk_localized_onboard_category_translation_category_language",
+ columnNames = {"category_id", "language"}
+ )
+)
public class LocalizedOnboardCategoryTranslation {🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In
`@src/main/java/org/sopt/kareer/domain/member/entity/LocalizedOnboardCategoryTranslation.java`
around lines 17 - 34, Add a DB-level unique constraint on (category_id,
language) to prevent duplicates: update the JPA entity
LocalizedOnboardCategoryTranslation by adding a uniqueConstraints entry on
`@Table` for the (category_id, language) pair, and create a database migration
that (a) resolves or deduplicates any existing duplicate rows for
localized_onboard_category_translation and (b) adds a UNIQUE constraint or
unique index on category_id and language. Also review callers like
LocalizedOnboardCategory.updateTranslation(), addTranslation() and any
repository usages that assume multiple rows per language to ensure they handle
the uniqueness guarantee after migration.
| public void updateProfile( | ||
| String targetJob, | ||
| LocalDate birthDate, | ||
| Country country, | ||
| String countryCode, | ||
| Degree degree, | ||
| String university, | ||
| String primaryMajor, | ||
| String universityCode, | ||
| String primaryMajorCode, | ||
| String secondaryMajor, | ||
| LanguageLevel languageLevel, | ||
| EnglishLevel englishLevel | ||
| ) { | ||
| this.targetJob = targetJob; | ||
| this.birthDate = birthDate; | ||
| this.country = country; | ||
| this.degree = degree; | ||
| this.university = university; | ||
| this.primaryMajor = primaryMajor; | ||
| this.countryCode = countryCode; | ||
| this.degreeCode = degree.getDescription(); | ||
| this.universityCode = universityCode; | ||
| this.primaryMajorCode = primaryMajorCode; | ||
| this.secondaryMajor = secondaryMajor; | ||
| this.languageLevel = languageLevel; | ||
| this.englishLevel = englishLevel; | ||
| this.englishLevelCode = englishLevel.getDescription(); | ||
| } |
There was a problem hiding this comment.
updateProfile() 메서드의 일관성 없는 파라미터 타입
updateProfile()에서 countryCode, universityCode, primaryMajorCode는 문자열 코드로 받지만, Degree와 EnglishLevel은 여전히 enum으로 받아 내부에서 getDescription()으로 변환합니다.
이는 호출자에게 혼란을 줄 수 있으며, i18n 전환의 일관성을 해칩니다. 모든 필드를 문자열 코드로 통일하거나, 명확한 API 계약을 문서화하는 것이 좋습니다.
♻️ 문자열 코드로 통일하는 제안
public void updateProfile(
String targetJob,
LocalDate birthDate,
String countryCode,
- Degree degree,
+ String degreeCode,
String universityCode,
String primaryMajorCode,
String secondaryMajor,
LanguageLevel languageLevel,
- EnglishLevel englishLevel
+ String englishLevelCode
) {
this.targetJob = targetJob;
this.birthDate = birthDate;
this.countryCode = countryCode;
- this.degreeCode = degree.getDescription();
+ this.degreeCode = degreeCode;
this.universityCode = universityCode;
this.primaryMajorCode = primaryMajorCode;
this.secondaryMajor = secondaryMajor;
this.languageLevel = languageLevel;
- this.englishLevelCode = englishLevel.getDescription();
+ this.englishLevelCode = englishLevelCode;
}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/main/java/org/sopt/kareer/domain/member/entity/Member.java` around lines
192 - 212, The updateProfile method mixes enum parameters (Degree, EnglishLevel)
with string codes for other fields which is inconsistent; change the
updateProfile signature to accept degreeCode and englishLevelCode as String
(instead of Degree and EnglishLevel), assign them directly to this.degreeCode
and this.englishLevelCode, and update all callers to pass the corresponding code
strings; keep the other parameters (countryCode, universityCode,
primaryMajorCode) unchanged so the API uniformly uses string codes.
| appendLine(sb, "country", member.getCountryCode() != null ? member.getCountryCode() : ""); | ||
| appendLine(sb, "university", member.getCountryCode()); | ||
| appendLine(sb, "primaryMajor", member.getPrimaryMajorCode()); |
There was a problem hiding this comment.
university에 국가 코드를 넣고 있습니다.
Line 32가 member.getCountryCode()를 다시 사용해서 대학 정보가 사라지고 country와 university가 같은 값으로 내려갑니다. 여기서는 member.getUniversityCode()를 써야 합니다.
🔧 수정 예시
- appendLine(sb, "university", member.getCountryCode());
+ appendLine(sb, "university", member.getUniversityCode());📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| appendLine(sb, "country", member.getCountryCode() != null ? member.getCountryCode() : ""); | |
| appendLine(sb, "university", member.getCountryCode()); | |
| appendLine(sb, "primaryMajor", member.getPrimaryMajorCode()); | |
| appendLine(sb, "country", member.getCountryCode() != null ? member.getCountryCode() : ""); | |
| appendLine(sb, "university", member.getUniversityCode()); | |
| appendLine(sb, "primaryMajor", member.getPrimaryMajorCode()); |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In
`@src/main/java/org/sopt/kareer/global/external/ai/builder/context/MemberContextBuilder.java`
around lines 31 - 33, In MemberContextBuilder the university field is
incorrectly populated using member.getCountryCode(), causing "country" and
"university" to share the same value; update the appendLine call that sets
"university" to use member.getUniversityCode() instead (locate the
appendLine(sb, "university", ...) call and replace the getter), leaving the
"country" and "primaryMajor" lines unchanged.
| assertThat(member.getSecondaryMajor()).isEqualTo("Statistic"); | ||
| assertThat(member.getLanguageLevel()).isEqualTo(LanguageLevel.LEVEL_3); | ||
| assertThat(member.getEnglishLevel()).isEqualTo(EnglishLevel.BEGINNER); | ||
| assertThat(member.getUniversityCode()).isEqualTo("beginner"); |
There was a problem hiding this comment.
영어 레벨 검증 getter가 잘못되었습니다.
Line 41은 getUniversityCode()를 다시 확인하고 있어 EnglishLevel.BEGINNER를 넣어도 테스트가 실패합니다. 여기서는 getEnglishLevelCode()를 검증해야 합니다.
🧪 수정 예시
- assertThat(member.getUniversityCode()).isEqualTo("beginner");
+ assertThat(member.getEnglishLevelCode()).isEqualTo("beginner");📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| assertThat(member.getUniversityCode()).isEqualTo("beginner"); | |
| assertThat(member.getEnglishLevelCode()).isEqualTo("beginner"); |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/test/java/org/sopt/kareer/domain/member/entity/MemberTest.java` at line
41, The test asserts the wrong getter: replace the call to
member.getUniversityCode() with the English level getter
member.getEnglishLevelCode() so the assertion compares the stored EnglishLevel
(e.g., EnglishLevel.BEGINNER) code value; update the assertion in MemberTest
(currently using getUniversityCode) to use getEnglishLevelCode() to validate
English level correctly.
Related issue 🛠
Work Description 📝
localized_onboard_category테이블에 온보딩/프로필에서 사용하는 모든 코드(국가, 전공, 학교, 학위, 영어 수준, 관심분야 등)를 저장하고, 자식 테이블인localized_onboard_category_translation에서 언어별 라벨을 관리해요.서비스 계층(
LocalizedOnboardQueryService)에서 요청의 Locale을 읽어언어 태그 → 언어 코드 → 기본값(en) 순으로 라벨을 조회하며,
라벨이 없을 경우 첫 번역값 또는 빈 문자열을 반환해요.
회원 정보는 DB에 항상 코드만 저장하고, 조회 시에만 해당 서비스를 통해 라벨로 변환하여 응답 DTO를 구성하는 구조에요.
ScreenShots 📷
To Reviewers 📢
Summary by CodeRabbit
릴리스 노트
새로운 기능
개선사항